package med.movyzer.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.StringTokenizer;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import med.movyzer.datastructs.Logger;
import med.movyzer.datastructs.MovementSeries;
import med.movyzer.datastructs.NoPSGFileException;
import med.movyzer.datastructs.MovementSeries.Movement;
import med.movyzer.util.ExtCalendar;

import org.jfree.data.time.TimeSeries;

public class PSGData implements MovyzerDataInterface{
	private MovementSeries data = new MovementSeries();
	private boolean isValidFile = false;
	private ExtCalendar startTime=new ExtCalendar();
	private ExtCalendar endTime=new ExtCalendar();
	private ExtCalendar epochPeriod=new ExtCalendar();

	public PSGData() {
	}

	public PSGData(File selectedFile) {
		loadFile(selectedFile.getPath(), null);
	}

	public static int preview(String path) throws Exception{
		int result=0;

		File file = new File(path);
		BufferedReader fReader=null;
		fReader = new BufferedReader(new FileReader(file));

		String line = null;

		int lineCounter=0;
		double movDuration;
		@SuppressWarnings("unused")
		double movIntensity;

		while((line = fReader.readLine()) != null)
		{
			lineCounter++;
			String regex = ("\"Beinbewegung\".+"); // This describes the sensor data pattern

			if (line.matches(regex)){
				SimpleDateFormat sd1 = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
				StringTokenizer st = new StringTokenizer(line,";");
				st.nextToken();
				st.nextToken();
				String time = st.nextToken().replace("\"", "");
				st.nextToken();
				String date = st.nextToken().replace("\"", "");
				String temp=st.nextToken();
				String[] temp2=temp.split(" ");
				movDuration = new Double (temp2[0].replace("\"", ""));
				movIntensity  = new Double (temp2[1].replace("\"", "").replace("(", "").replace(")", ""));

				ExtCalendar movStartTime = new ExtCalendar(), movEndTime = new ExtCalendar();
				movStartTime.setTime(sd1.parse(date+" "+time));
				movEndTime = (ExtCalendar) movStartTime.clone();

				movEndTime.add(Calendar.SECOND, (int) movDuration);
				result++;
			}
			
		}
				
		fReader.close();
		
		if (result==0){
			throw new NoPSGFileException();
		}
		
		return result;
	}

	public boolean loadFile(String path, JFrame frame){
		Logger.addEntry("Loading PSG-File: "+path);
		File file = new File(path);
		BufferedReader fReader=null;
		try {
			fReader = new BufferedReader(new FileReader(file));
		} catch (FileNotFoundException e) {
			Logger.addEntry("Error loading file: "+path+", File not found");
			JOptionPane.showMessageDialog(frame, "Error loading file: "+path+"\nFile not found");
			return false;
		}

		String line = null;

		// dirty Hack
		try {
			SimpleDateFormat sd = new SimpleDateFormat( "HH:mm:ss" );
			epochPeriod.setTime(sd.parse("00:00:01"));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		try {
			int lineCounter=0;
			boolean firstMovement = true;
			double movDuration;
			double movIntensity;

			while((line = fReader.readLine()) != null)
			{
				lineCounter++;

				try{

					String regex = ("\"Beinbewegung\".+"); // This describes the sensor data pattern

					if (line.matches(regex)){
						isValidFile = true;

						SimpleDateFormat sd = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
						StringTokenizer st = new StringTokenizer(line,";");
						st.nextToken();
						st.nextToken();
						String time = st.nextToken().replace("\"", "");
						st.nextToken();
						String date = st.nextToken().replace("\"", "");
						String temp=st.nextToken();
						String[] temp2=temp.split(" ");
						movDuration = new Double (temp2[0].replace("\"", ""));
						movIntensity  = new Double (temp2[1].replace("\"", "").replace("(", "").replace(")", ""));

						ExtCalendar movStartTime = new ExtCalendar(), movEndTime = new ExtCalendar();
						movStartTime.setTime(sd.parse(date+" "+time));
						movEndTime = (ExtCalendar) movStartTime.clone();

						movEndTime.add(Calendar.SECOND, (int) movDuration);

						// End of Extraction

						data.addMovement(new Movement(movStartTime, movEndTime, movIntensity));

						// Extract starting time from first encounter of a movement in the file
						if (firstMovement){ 
							startTime=(ExtCalendar) movStartTime.clone();
							firstMovement = false;
						} 
						endTime = (ExtCalendar) movEndTime.clone();

						//System.out.println("detected movement: start "+movStartTime.getHMS()+" end "+movEndTime.getHMS()+" intens. "+movIntensity);
					}
				}catch(Exception e){
					Logger.addEntry("	Error: malformed line @ line"+lineCounter);
				}
				data.setStartTime(startTime);
				data.setEndTime(endTime);
			}
			
			fReader.close();
			
			if (startTime.equals(endTime)){
				throw new NoPSGFileException();
			}

		}catch (IOException e) {
			Logger.addEntry("	Error loading file: "+path+"\nError reading line");
			JOptionPane.showMessageDialog(frame, "Error loading file: "+path+"\nError reading line");
			return false;
		}
		catch (NoPSGFileException e) {
			Logger.addEntry("	Error loading file: "+path+"\nFile does not seem to be a valid PSG file");
			JOptionPane.showMessageDialog(frame, "Error loading file: "+path+"\nFile does not seem to be a valid PSG file");
			return false;
		}
		Logger.addEntry("Start Time: "+startTime.getTime().toString());
		Logger.addEntry("End Time: "+endTime.getTime().toString());
		Logger.addEntry("PSG-File loaded, "+data.size()+" entries found");
		return true;
	}

	public TimeSeries getTimeSeries(){
		return  data.getTimeSeries(1);
	}

	public ExtCalendar getStartTime() {
		return startTime;
	}

	public ExtCalendar getEndTime() {
		return endTime;
	}
		
	public MovementSeries getMData() {
		return data;
	}

	public ExtCalendar getEpochPeriod() {
		return epochPeriod;
	}

	public int getPeriodsCount(){
		ExtCalendar time=(ExtCalendar) startTime.clone();
		int i=0;
		while(time.before(endTime)){
			time.addTime(epochPeriod);
			i++;
		}
		return i;
	}

	public boolean validate(){
		return isValidFile;
	}

	// the following is just to satisfy the Interface requirements. For PSG these methods are not relevant, they won't ever be called.
	
	@Override
	public ArrayList<Integer[]> getData() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public MovementSeries getMovementSeries(int timeframeThreshold) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getShift() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean isMobileFile() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isRawFile() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void setEarthGravity(int earthGravity) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setEndShowTime(ExtCalendar endtime) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setShift(int shift) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setTreshold(int treshold) {
		// TODO Auto-generated method stub
		
	}
}
